package com.hcmu.networklibs.rss;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;

class RSSParser extends DefaultHandler {
    public static SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
    private String urlString;
    private RSSFeed rssFeed;
    private StringBuilder textBuilder;
    private RSSItem rssItem;
    private boolean imgStatus;

    public RSSParser(String url) {
        this.urlString = url;
        this.textBuilder = new StringBuilder();
    }

    public void parse() {
        InputStream urlInputStream = null;
        SAXParserFactory spf;
        SAXParser sp;

        try {
            URL url = new URL(this.urlString);
            urlInputStream = url.openConnection().getInputStream();
            InputSource is = new InputSource(urlInputStream);
            is.setEncoding("UTF-8");

            spf = SAXParserFactory.newInstance();
            if (spf != null) {
                sp = spf.newSAXParser();
                sp.parse(is, this);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (urlInputStream != null) urlInputStream.close();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    public RSSFeed getFeed() {
        return (this.rssFeed);
    }

    
    /**
     * 
     */
    public void startElement(String uri, String localName, String qName,
                             Attributes attributes) {
        if (qName.equalsIgnoreCase("channel"))
            this.rssFeed = new RSSFeed();
        else if (qName.equalsIgnoreCase("item") && (this.rssFeed != null)) {
            this.rssItem = new RSSItem();
            this.rssFeed.addItem(this.rssItem);
        } else if (qName.equalsIgnoreCase("image") && (this.rssFeed != null))
            this.imgStatus = true;
    }

    
    /**
     * 
     */
    public void endElement(String uri, String localName, String qName) {
        if (this.rssFeed == null)
            return;

        if (qName.equalsIgnoreCase("item")){
            this.rssItem = null;
        }
        else if (qName.equalsIgnoreCase("image")){
            this.imgStatus = false;
        }else if (qName.equalsIgnoreCase("title")) {
            if (this.rssItem != null) this.rssItem.title = this.textBuilder.toString().trim();
            else if (this.imgStatus) this.rssFeed.imageTitle = this.textBuilder.toString().trim();
            else this.rssFeed.title = this.textBuilder.toString().trim();
            
        } else if (qName.equalsIgnoreCase("link")) {
            if (this.rssItem != null) this.rssItem.link = this.textBuilder.toString().trim();
            else if (this.imgStatus) this.rssFeed.imageLink = this.textBuilder.toString().trim();
            else this.rssFeed.link = this.textBuilder.toString().trim();
            
        } else if (qName.equalsIgnoreCase("description")) {
            if (this.rssItem != null) this.rssItem.description = this.textBuilder.toString().trim();
            else this.rssFeed.description = this.textBuilder.toString().trim();
            
        } else if (qName.equalsIgnoreCase("url") && this.imgStatus)
            this.rssFeed.imageUrl = this.textBuilder.toString().trim();

        else if (qName.equalsIgnoreCase("language"))
            this.rssFeed.language = this.textBuilder.toString().trim();

        else if (qName.equalsIgnoreCase("generator"))
            this.rssFeed.generator = this.textBuilder.toString().trim();

        else if (qName.equalsIgnoreCase("copyright"))
            this.rssFeed.copyright = this.textBuilder.toString().trim();

        else if (qName.equalsIgnoreCase("content:encoded")){
        	this.rssFeed.content = this.textBuilder.toString().trim();
        	Log.e("content", ""+ this.rssFeed.content);
        }
        
        else if (qName.equalsIgnoreCase("pubDate") && (this.rssItem != null)) {
            try {
                this.rssItem.pubDate = sdf.parse(this.textBuilder.toString().trim());
            } catch (ParseException e) {
                throw new RuntimeException();
            }
        } else if (qName.equalsIgnoreCase("category") && (this.rssItem != null)){
            this.rssFeed.addItem(this.textBuilder.toString().trim(), this.rssItem);
        }
        
        this.textBuilder.setLength(0);
    	
    	
 /*   	if(rssFeed != null && rssItem == null) {
			// Parse feed properties
			try {
				if (qName != null && qName.length() > 0) {
				    String methodName = "set" + qName.substring(0, 1).toUpperCase() + qName.substring(1);
				    Method method = rssFeed.getClass().getMethod(methodName, String.class);
				    method.invoke(rssFeed, textBuilder.toString());
				}
			} catch (SecurityException e) {
			} catch (NoSuchMethodException e) {
			} catch (IllegalArgumentException e) {
			} catch (IllegalAccessException e) {
			} catch (InvocationTargetException e) {
			}
			
		} else if (rssItem != null) {
			// Parse item properties
			
			try {
				if(qName.equals("content:encoded")) 
					qName = "content";
				String methodName = "set" + qName.substring(0, 1).toUpperCase() + qName.substring(1);
				Method method = rssItem.getClass().getMethod(methodName, String.class);
				method.invoke(rssItem, textBuilder.toString());
			} catch (SecurityException e) {
			} catch (NoSuchMethodException e) {
			} catch (IllegalArgumentException e) {
			} catch (IllegalAccessException e) {
			} catch (InvocationTargetException e) {
			}
		}*/
    	
    }

    public void characters(char[] ch, int start, int length) {
        this.textBuilder.append(ch, start, length);
    }
}

